Unique Index {mongodb} {prisma}
MongoDB에서 고유제약조건을 걸기 위해선 어떻게 해야할까? 그리고 PrismaORM을 사용할 때 @unique
속성만 추가한다고 바로 적용이 되지 않는데 prisma push를 해야하는걸까?
AI Response (ChatGPT 4o)
좋은 질문이에요. MongoDB와 PrismaORM 모두에서 고유 제약 조건 (unique constraint) 을 다룰 때 주의할 점이 있습니다. 하나씩 정리해드릴게요.
✅ MongoDB에서 고유 제약 조건 걸기
MongoDB는 스키마리스(NoSQL) 이지만, 인덱스를 이용해서 유일 제약 조건을 설정할 수 있습니다.
방법 1. MongoDB 쉘이나 드라이버에서 인덱스 생성
db.users.createIndex({ email: 1 }, { unique: true })
-
users
컬렉션의email
필드에 대해 unique 인덱스를 생성합니다. -
이미 중복 데이터가 있다면 에러가 발생합니다.
방법 2. Mongoose 사용 시
const userSchema = new Schema({
email: { type: String, unique: true }
})
단, Mongoose의 unique: true
는 MongoDB 인덱스를 생성하라는 힌트일 뿐이고, 자동으로 보장되지 않기 때문에 실제 인덱스가 생성됐는지 확인이 필요합니다.
✅ Prisma ORM에서 @unique
설정의 동작 방식
Prisma ORM에서는 다음처럼 모델에 @unique
데코레이터를 붙여 유니크 제약을 정의합니다.
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
email String @unique
}
하지만! Prisma에서는 이걸 정의했다고 해서 바로 DB에 반영되는 건 아닙니다.
💡 Prisma에서 @unique
사용 후 해야 할 작업
작업 | 설명 |
---|---|
npx prisma db push |
현재 Prisma schema를 기반으로 MongoDB에 인덱스를 생성하거나 스키마 변경사항을 반영합니다. 빠르게 반영할 때 사용. |
npx prisma migrate dev |
PostgreSQL, MySQL 등 관계형 DB에서 마이그레이션 파일을 생성하고 실행. MongoDB에서는 비추천. |
MongoDB에서는 보통 prisma db push
를 사용해야 합니다.
✔️ 요약:
@unique
속성을 선언하고, 반드시npx prisma db push
를 실행해야 MongoDB에 unique 인덱스가 생성됩니다.
🔍 주의사항
- 이미 중복된 데이터가 존재하면
db push
시 실패합니다.- MongoDB는 인덱스를 생성할 때, 기존 데이터에도 유일성을 검사합니다.
- 중복 데이터가 있다면 인덱스 생성이 거부됩니다.
- Prisma에서는 현재 MongoDB에 대해 마이그레이션을 지원하지 않으며,
db push
방식만 사용해야 합니다. - Prisma MongoDB는 내부적으로
_id
외 필드에도 인덱스를 생성할 수 있지만, 인덱스 상태를 관리하지는 않기 때문에 MongoDB Compass나 CLI로 확인하는 습관이 좋습니다.
2025-04-22 Troubleshooting) @unique
attribute는 null 중복을 허용하지 않는다.
In MongoDB (and by extension, Prisma with MongoDB), a unique index that allows multiple null values behaves differently than in traditional SQL databases:
- MongoDB allows multiple documents with the same field set to null for a field with a unique index.
- But Prisma, when using @unique, emulates SQL behavior, not allowing multiple nulls.
If you want a field to be conditionally unique only when it’s not null, you need to manually create a partial index in MongoDB outside of Prisma, since Prisma doesn’t currently support partial indexes natively.
🔧 Step-by-step workaround:
- Remove @unique from Prisma schema:
model MyModel {
id String @id @default(auto()) @map("_id") @db.ObjectId
email String? // ← we want this to be unique only if NOT null
}
- Generate Prisma Client:
npx prisma generate
- Create the partial index manually in MongoDB shell:
db.mymodels.createIndex(
{ email: 1 },
{
unique: true,
partialFilterExpression: { email: { $exists: true, $ne: null } }
}
)
This ensures:
- Multiple nulls are allowed
- Only non-null values are required to be unique
- Prisma currently does not support partial indexes directly in the schema — upvote the GitHub issue if it’s important for you.
🧪 예제
model Product {
id String @id @default(auto()) @map("_id") @db.ObjectId
sku String @unique
name String
}
npx prisma db push
MongoDB에 접속해서 인덱스 확인:
db.product.getIndexes()
결과:
[
{ "key": { "_id": 1 }, "name": "_id_", "unique": true },
{ "key": { "sku": 1 }, "name": "Product_sku_key", "unique": true }
]
✨ 추가 팁
- 유니크 인덱스 외에도 Prisma에서 MongoDB용 복합 인덱스도 선언할 수 있습니다:
@@unique([firstName, lastName])
- Prisma MongoDB를 사용할 때 MongoDB 버전은 4.2 이상을 권장합니다.
필요하다면, Prisma + MongoDB 구조에서의 실전 유스케이스 (e.g. 회원 가입 시 중복 이메일 처리, 유니크 실패 시 예외 핸들링) 도 알려드릴게요. 원하시나요?